package datatype;

import org.junit.Test;

import java.util.Arrays;

/**
 * @author DuJiabao
 * @create 2020-12-29 23:44
 */
public class ArrayQueue<Item> {
    private Item[] queue = (Item[]) new Object[10];
    private int head = 0;
    private int count = 0;

    @Test
    public void test() {
        ArrayQueue<Integer> arrayQueue = new ArrayQueue<Integer>();
        arrayQueue.enqueue(10);
        System.out.println(arrayQueue.dequeue());
        for (int i = 0; i < 10; i++) {
            arrayQueue.enqueue(i);
        }
        System.out.println(arrayQueue.toString());
        for (int i = 0; i < 3; i++) {
            System.out.println(arrayQueue.dequeue());
        }
        System.out.println(arrayQueue.toString());
        for (int i = 0; i < 10; i++) {
            arrayQueue.enqueue(i);
        }
        System.out.println(arrayQueue.toString());
        for (int i = 0; i < 18; i++) {
            System.out.println(arrayQueue.dequeue());
        }
    }

    public ArrayQueue() {
    }

    public void enqueue(Item item) {
        if (queue.length <= count) {
            resize(2 * queue.length);
        }
        int pos = count + head < queue.length ? count + head : count + head - queue.length;
        queue[pos] = item;
        count++;
    }

    public Item dequeue() {
        if (count <= 0) {
            return null;
        }
        count--;
        return queue[head++];
    }

    private void resize(int length) {
        Item[] new_queue = (Item[]) new Object[length];
        for (int i = 0; i < count; i++) {
            if (i + head < queue.length) {
                new_queue[i] = queue[i + head];
            } else {
                new_queue[i] = queue[i + head - queue.length];
            }
        }
        queue = new_queue;
        head = 0;
    }


    public boolean isEmpty() {
        return count == 0;
    }

    public int size() {
        return count;
    }

    public String forEach() {
        StringBuilder result = new StringBuilder("[ ");
        for (int i = 0; i < count; i++) {
            if (i + head < queue.length) {
                result.append(queue[i + head]);
            } else {
                result.append(queue[i + head - queue.length]);
            }
            result.append(" ");
        }
        return result + "]";
    }

    @Override
    public String toString() {
        return "ArrayQueue{" +
                "head=" + head +
                ", count=" + count +
                ", queue=" + forEach() +
                '}';
    }
}
